import React, { memo, useEffect, useRef, useState } from 'react'
import type { FC, ReactNode } from 'react'
import { Slider } from 'antd'

import {
  ContentWrapper,
  LeftWrapper,
  PlayerContentWrapper,
  PlayerWrapper,
  Right1Wrapper,
  Right2Wrapper
} from './style'
import { shallowEqualApp, useAppDispatch, useAppSelector } from '@/store'
import { getSongPlayUrl } from '@/utlis/getAudioSrc'
import { fetchByIdGetLyricAction } from '@/store/modules/audio'
import { forMatTime } from '@/utlis/format'
import { useChangeAudio } from '@/hooks/useChangeAudio'

interface IProps {
  children?: ReactNode
}

const Player: FC<IProps> = () => {
  const [isPlaying, setIsPlaying] = useState(false) // 是否播放
  const [audioDuration, setAudioDuration] = useState(0) // 音频时长
  const [audioCurrentTime, setAudioCurrentTime] = useState(0) // 当前播放时间
  const [audioProgress, setAudioProgress] = useState(0) // 进度条进度
  const [isDraging, setIsDraging] = useState(false) // 进度条是否在拖动状态

  // 获得歌曲相关的仓库信息
  const { currentSong, playSongList } = useAppSelector(
    (state) => ({
      playSongList: state.audio.playSongList,
      playSongIndex: state.audio.playSongIndex,
      currentSong: state.audio.currentSong
    }),
    shallowEqualApp
  )

  const dispatch = useAppDispatch()
  const audioRef = useRef<HTMLAudioElement>(null)

  // 当歌曲改变的时候，自动播放
  const autoPlayAudio = () => {
    if (audioRef.current) {
      audioRef.current.src = getSongPlayUrl(currentSong.id)
      audioRef.current?.play().catch(() => setIsPlaying(false))
      setAudioDuration(currentSong.dt)
    }
  }

  // 歌曲发生变化是获得歌词信息
  const getSongLyric = () => {
    if (currentSong.id) {
      dispatch(fetchByIdGetLyricAction(currentSong.id))
    }
  }

  useEffect(() => {
    // 当歌曲改变的时候，自动播放
    autoPlayAudio()
    // 获取当前的歌词信息
    getSongLyric()
    setIsPlaying(true)
  }, [currentSong])

  // 点击播放按钮
  const playAudio = () => {
    // 1.控制播放器的播放/暂停
    isPlaying
      ? audioRef.current?.pause()
      : audioRef.current?.play().catch((err) => {
          console.log(err)
          console.log('播放失败')
          setIsPlaying(false)
        })

    // 2.改变isPlaying的状态
    setIsPlaying(!isPlaying)
  }

  // 点击上一首和下一首的hooks
  const { prevAudio, nextAudio } = useChangeAudio()

  // 监控音乐的播放
  const handleTimeUpdate = () => {
    if (!isDraging) {
      // 设置当前播放时间
      let currentTime = audioRef.current?.currentTime
      if (audioRef.current) {
        currentTime = audioRef.current.currentTime * 1000
      }
      setAudioCurrentTime(currentTime as number)
      // 计算进度条进度
      setAudioProgress(
        ((currentTime as number) / (audioDuration as number)) * 100
      )
    }
  }

  // 拖动进度条
  const sliderChangeHandler = (value: number) => {
    setIsDraging(true)
    setAudioProgress(value)
    setAudioCurrentTime((audioProgress / 100) * audioDuration)
  }

  // 松开进度条
  const sliderChangeUpHandler = () => {
    setIsDraging(false)
    if (audioRef.current) {
      audioRef.current.currentTime =
        ((audioProgress / 100) * audioDuration) / 1000
    }
    isPlaying
      ? audioRef.current?.play().then(() => setIsPlaying(true))
      : audioRef.current?.pause()
  }

  return (
    <PlayerWrapper>
      {/* 音乐播放器 */}
      <audio ref={audioRef} onTimeUpdate={handleTimeUpdate}></audio>

      {/* 整个大背景 */}
      <div className="player_bg sprite_playbar"></div>
      <div className="right_icon">
        <div className="left sprite_playbar"></div>
        <div className="right sprite_playbar"></div>
      </div>

      {/* 音乐播放控制中心 */}
      <PlayerContentWrapper>
        <LeftWrapper className="left" $isplaying={isPlaying ? 1 : 0}>
          <a className="btn prev sprite_playbar" onClick={prevAudio}></a>
          <a className="btn play sprite_playbar" onClick={playAudio}></a>
          <a className="btn next sprite_playbar" onClick={nextAudio}></a>
        </LeftWrapper>

        <ContentWrapper className="content">
          <div className="poster">
            <img className="image" src={currentSong?.al?.picUrl} />
            <a className="poster_mask sprite_playbar"></a>
          </div>
          <div className="progress">
            <div className="songinfo">
              <a className="songname">{currentSong?.name}</a>
              <a className="artname">
                {currentSong?.ar ? currentSong?.ar[0]?.name : ''}
              </a>
            </div>
            <Slider
              step={0.5}
              tooltip={{ formatter: null }}
              value={audioProgress}
              onChange={sliderChangeHandler}
              onChangeComplete={sliderChangeUpHandler}
            ></Slider>
          </div>
          <div className="time">
            <span className="current">{forMatTime(audioCurrentTime)}</span>
            <span className="divider">/</span>
            <span className="duration">{forMatTime(audioDuration)}</span>
          </div>
        </ContentWrapper>

        <Right1Wrapper className="right_1">
          <a className="btn pip sprite_pip"></a>
          <a className="btn favor sprite_playbar"></a>
          <a className="btn share sprite_playbar"></a>
        </Right1Wrapper>

        <Right2Wrapper className="right_2">
          <a className="btn voice sprite_playbar"></a>
          <a className="btn mode sprite_playbar"></a>
          <div className="audio_list">
            <a className="icon sprite_playbar"></a>
            <span className="text">{playSongList.length}</span>
          </div>
          <a className="quality_audio sprite_qual"></a>
        </Right2Wrapper>
      </PlayerContentWrapper>
    </PlayerWrapper>
  )
}

export default memo(Player)
